<template>
  <div id="tags-view-container" class="tags-view-container">
    <s-scroll-pane class="tags-view-wrapper">
      <router-link
        ref="ref"
        :to="{ path: '/main' }"
        class="tags-view-item"
        :class="isActive({ href: 'main' }) ? 'active' : ''"
        tag="span"
      >
        首页
      </router-link>
      <router-link
        v-for="(item, index) in visitedViews"
        :key="index"
        ref="ref"
        :to="{ path: '/' + item.href }"
        class="tags-view-item"
        :class="isActive(item) ? 'active' : ''"
        tag="span"
        @click.middle="closeSelectedTag(item)"
        @contextmenu.prevent="openMenu(item, $event)"
      >
        {{ item.name }}
        <span
          class="el-icon-close"
          @click.prevent.stop="closeSelectedTag(item)"
        />
      </router-link>
    </s-scroll-pane>
    <ul
      v-show="visible"
      :style="{ left: left + 'px', top: top + 'px' }"
      class="contextmenu"
    >
      <li @click="refreshSelectedTag(selectedTag)">刷新</li>
      <li @click="closeSelectedTag(selectedTag)">关闭</li>
      <li @click="closeOthersTags(selectedTag)">关闭其它</li>
      <li @click="closeAllTags">关闭所有</li>
    </ul>
  </div>
</template>
<script>
import sScrollPane from "../s-scroll-pane/s-scroll-pane.vue";
export default {
  name: "sTagsView",
  components: { "s-scroll-pane": sScrollPane },
  data() {
    return {
      visible: false,
      top: 0,
      left: 0,
      selectedTag: {}
    };
  },
  props: {},
  watch: {
    visible(value) {
      if (value) {
        document.body.addEventListener("click", this.closeMenu);
      } else {
        document.body.removeEventListener("click", this.closeMenu);
      }
    }
  },
  computed: {
    visitedViews() {
      const path = this.$route.path;
      const data = this.$store.state.menus.visitedViews.filter(v => {
        return "/" + v.href === path;
      });
      if (data.length) {
        this.$store.commit("menus/setBreadcrumb", data[0].breadcrumb);
        this.$store.commit("menus/setHref", data[0].href);
        this.$store.commit("menus/setChildrenHref", data[0].children || []);
      } else {
        if (path === "/main") {
          this.$store.commit("menus/emptyBreadcrumb");
          this.$store.commit("menus/emptyHref");
          this.$store.commit("menus/emptyChildrenHref");
        }
      }
      return this.$store.state.menus.visitedViews;
    }
  },
  methods: {
    isActive(route) {
      return "/" + route.href === this.$route.path;
    },
    closeSelectedTag(view) {
      this.$store.dispatch("menus/delVisitedViews", view).then(visitedViews => {
        if (this.isActive(view)) {
          this.toLastView(visitedViews, view);
        }
      });
    },
    refreshSelectedTag() {
      this.$nextTick(() => {
        this.$router.go(0);
      });
    },
    closeOthersTags(selectedTag) {
      this.$store.dispatch("menus/delOthersViews", selectedTag).then(() => {
        this.$router.push({ path: "/" + selectedTag.href });
      });
    },
    closeAllTags() {
      this.$store.commit("menus/emptyVisitedViews");
      this.$router.push({ path: "/main" });
    },
    toLastView(visitedViews) {
      const latestView = visitedViews.slice(-1)[0];
      if (latestView) {
        this.$router.push("/" + latestView.href);
      } else {
        this.$router.push("/");
      }
    },
    openMenu(tag, e) {
      const menuMinWidth = 105;
      const offsetLeft = this.$el.getBoundingClientRect().left; // container margin left
      const offsetWidth = this.$el.offsetWidth; // container width
      const maxLeft = offsetWidth - menuMinWidth; // left boundary
      const left = e.clientX - offsetLeft + 15; // 15: margin right
      if (left > maxLeft) {
        this.left = maxLeft;
      } else {
        this.left = left;
      }

      this.top = e.clientY;
      this.visible = true;
      this.selectedTag = tag;
    },
    closeMenu() {
      this.visible = false;
    }
  }
};
</script>
<style lang="scss" scoped>
@import "s-tags-view.scss";
</style>
